package com.iplatform.commons.exception.handler;


import com.iplatform.commons.exception.CustomException;
import com.iplatform.commons.utils.CommResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.nio.file.AccessDeniedException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

/**
 * 全局异常捕获
 *
 * @author Dair
 * @since 2020/12/3
 */
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
	
	private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
	
	/**
	 * 定义要捕获的异常 可以多个 @ExceptionHandler({})
	 *
	 * @param request  request
	 * @param ex       exception
	 * @param response response
	 * @return 响应结果
	 */
	@ExceptionHandler(GlobalException.class)
	public ResponseEntity customExceptionHandler(HttpServletRequest request, final Exception ex, HttpServletResponse response) {
		log.error("UserPasswordNotMatchException" + ex.getMessage());
		ex.printStackTrace();
		ex.fillInStackTrace();
		log.error("customExceptionHandler", ex.getLocalizedMessage());
		return new ResponseEntity(new CommResponse<>(ex.getMessage(), Boolean.FALSE), HttpStatus.BAD_REQUEST);
	}
	
	/**
	 * 无权限异常处理
	 *
	 * @param ex
	 * @return
	 */
	@ExceptionHandler(AccessDeniedException.class)
	public ResponseEntity handleAccessDeniedException(AccessDeniedException ex, HttpServletResponse response) {
		log.error("UserPasswordNotMatchException" + ex.getMessage());
		ex.printStackTrace();
		ex.fillInStackTrace();
		log.error("handleAccessDeniedException", ex.getLocalizedMessage());
		return new ResponseEntity(new CommResponse<>("无权限访问接口", Boolean.FALSE), HttpStatus.FORBIDDEN);
		
	}
	
	
	/**
	 * 重写方法参数错误异常处理方法
	 *
	 * @param ex
	 * @param headers
	 * @param status
	 * @param request
	 * @return
	 */
	@Override
	protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
		log.error("MethodArgumentNotValidException" + ex.getMessage());
		ex.printStackTrace();
		ex.fillInStackTrace();
		log.error("handleMethodArgumentNotValid", ex.getLocalizedMessage());
		List<ObjectError> allErrors = ex.getBindingResult().getAllErrors();
		if (!CollectionUtils.isEmpty(allErrors)) {
			return new ResponseEntity(new CommResponse<>(allErrors.get(0).getDefaultMessage(), Boolean.FALSE), HttpStatus.BAD_REQUEST);
		}
		return new ResponseEntity(new CommResponse<>("参数错误,请检查参数", Boolean.FALSE), HttpStatus.BAD_REQUEST);
		
	}
	
	/**
	 * DataIntegrityViolationException
	 */
	@ExceptionHandler(DataIntegrityViolationException.class)
	public ResponseEntity handlerDataIntegrityViolationException(DataIntegrityViolationException ex) {
		log.error("handlerDataIntegrityViolationException" + ex.getMessage());
		ex.printStackTrace();
		ex.fillInStackTrace();
		log.error("handlerDataIntegrityViolationException", ex.getLocalizedMessage());
		return new ResponseEntity(new CommResponse<>(ex.getMessage(), Boolean.FALSE), HttpStatus.BAD_REQUEST);
		
	}
	
	@ExceptionHandler(Exception.class)
	public ResponseEntity handlerException(Exception ex) {
		log.error("Exception" + ex.getMessage());
		ex.printStackTrace();
		ex.fillInStackTrace();
		log.error("handlerException", ex.getLocalizedMessage());
		return new ResponseEntity(new CommResponse<>(ex.getMessage(), Boolean.FALSE), HttpStatus.BAD_REQUEST);
	}
	
	@ExceptionHandler(ConstraintViolationException.class)
	public ResponseEntity handleValidationException(ConstraintViolationException e) {
		e.printStackTrace();
		e.fillInStackTrace();
		log.error("handleValidationException", e.getLocalizedMessage());
		for (ConstraintViolation<?> s : e.getConstraintViolations()) {
			return new ResponseEntity(new CommResponse<>(s.getInvalidValue() + ": " + s.getMessage(), Boolean.FALSE), HttpStatus.BAD_REQUEST);
		}
		return new ResponseEntity(new CommResponse<>("请求参数不合法", Boolean.FALSE), HttpStatus.BAD_REQUEST);
		
	}
	
}
